import axios, { AxiosInstance, AxiosResponse } from 'axios';
import { ConfigurationManager } from './configurationManager';

export interface CompletionItem {
    label: string;
    kind: string;
    detail: string;
    documentation: string;
    insertText: string;
    sortOrder: number;
    confidence: number;
    isSnippet: boolean;
    source: string;
}

export interface CodeContext {
    filePath: string;
    code: string;
    cursorLine: number;
    cursorColumn: number;
    prefix: string;
    suffix: string;
    language: string;
    projectRoot: string;
    gnBuildFile?: string;
    includes?: string[];
    namespace?: string;
    className?: string;
    functionName?: string;
    metadata?: Record<string, any>;
}

export interface CompletionRequest {
    context: CodeContext;
    maxResults?: number;
    useLLM?: boolean;
    includeSnippets?: boolean;
    timeout?: number;
}

export interface GenerationRequest {
    context: CodeContext;
    prompt: string;
    generationType?: string;
    maxLength?: number;
    temperature?: number;
    followCodingStandard?: boolean;
}

export interface AnalysisRequest {
    context: CodeContext;
    analysisTypes?: string[];
    useCodeQL?: boolean;
    severityLevel?: string;
    includeFix?: boolean;
}

export interface RestResult<T> {
    code: number;
    message: string;
    data: T;
    timestamp: number;
    traceId: string;
}

export class ApiClient {
    private client: AxiosInstance;
    private configManager: ConfigurationManager;

    constructor(configManager: ConfigurationManager) {
        this.configManager = configManager;
        this.client = axios.create({
            baseURL: this.configManager.getServiceUrl(),
            timeout: this.configManager.getTimeout(),
            headers: {
                'Content-Type': 'application/json'
            }
        });

        // 添加请求拦截器
        this.client.interceptors.request.use(
            (config) => {
                console.log(`发送请求: ${config.method?.toUpperCase()} ${config.url}`);
                return config;
            },
            (error) => {
                console.error('请求错误:', error);
                return Promise.reject(error);
            }
        );

        // 添加响应拦截器
        this.client.interceptors.response.use(
            (response: AxiosResponse<RestResult<any>>) => {
                console.log(`收到响应: ${response.status} ${response.config.url}`);
                return response;
            },
            (error) => {
                console.error('响应错误:', error);
                return Promise.reject(error);
            }
        );
    }

    async agentChat(message: string, conversationId?: string, context?: Partial<CodeContext>): Promise<{ reply: string; conversationId: string; toolCalls?: any[] }>
    {
        try {
            const response = await this.client.post<RestResult<{ reply: string; conversationId: string; toolCalls?: any[] }>>(
                '/api/agent/chat',
                {
                    message,
                    conversationId,
                    context
                }
            );
            return response.data.data;
        } catch (error) {
            console.error('Agent对话失败:', error);
            throw new Error(`Agent对话失败: ${error}`);
        }
    }

    async getCompletions(request: CompletionRequest): Promise<CompletionItem[]> {
        try {
            const response = await this.client.post<RestResult<CompletionItem[]>>(
                '/api/completion/suggest',
                request
            );
            return response.data.data || [];
        } catch (error) {
            console.error('获取代码补全失败:', error);
            throw new Error(`获取代码补全失败: ${error}`);
        }
    }

    async getFunctionCompletions(request: CompletionRequest): Promise<CompletionItem[]> {
        try {
            const response = await this.client.post<RestResult<CompletionItem[]>>(
                '/api/completion/function',
                request
            );
            return response.data.data || [];
        } catch (error) {
            console.error('获取函数补全失败:', error);
            throw new Error(`获取函数补全失败: ${error}`);
        }
    }

    async getGnCompletions(request: CompletionRequest): Promise<CompletionItem[]> {
        try {
            const response = await this.client.post<RestResult<CompletionItem[]>>(
                '/api/completion/gn',
                request
            );
            return response.data.data || [];
        } catch (error) {
            console.error('获取GN补全失败:', error);
            throw new Error(`获取GN补全失败: ${error}`);
        }
    }

    async generateCode(request: GenerationRequest): Promise<string> {
        try {
            const response = await this.client.post<RestResult<{ code: string }>>(
                '/api/generation/generate',
                request
            );
            return response.data.data?.code || '';
        } catch (error) {
            console.error('代码生成失败:', error);
            throw new Error(`代码生成失败: ${error}`);
        }
    }

    async analyzeCode(request: AnalysisRequest): Promise<any> {
        try {
            const response = await this.client.post<RestResult<any>>(
                '/api/analysis/analyze',
                request
            );
            return response.data.data;
        } catch (error) {
            console.error('代码分析失败:', error);
            throw new Error(`代码分析失败: ${error}`);
        }
    }

    async generateWithLLM(prompt: string, systemPrompt?: string): Promise<string> {
        try {
            const response = await this.client.post<RestResult<{ code: string }>>(
                '/api/llm/generate',
                {
                    prompt,
                    systemPrompt,
                    model: 'glm-4',
                    temperature: 0.7,
                    maxTokens: 2000
                }
            );
            return response.data.data?.code || '';
        } catch (error) {
            console.error('LLM生成失败:', error);
            throw new Error(`LLM生成失败: ${error}`);
        }
    }

    async healthCheck(): Promise<boolean> {
        try {
            const response = await this.client.get('/api/completion/health');
            return response.status === 200;
        } catch (error) {
            console.error('健康检查失败:', error);
            return false;
        }
    }
}
